--[[ Serverside Custom Addon file Base ]]--
local SM = {}
CreateConVar( "SM_veinlimit", "65" )
CreateConVar( "SM_respawn_time", "10" )
CreateConVar( "SM_respawn_count", "5" )
CreateConVar( "SM_respawn_maxlife", "10" )

SM.model = "models/ce_ls3additional/fusion_generator/fusion_generator_huge.mdl" --stores model

SM.resources = {} -- Used for sellingvalues
SM.gResources = {} -- Used for veins and rarity
SM.gResourcesTot = 0
SM.VeinSizes = {}
SM.veins = {} -- Used for storing the veins
SM.spawns = {}
SM.ready = false
local status = false

SM.VeinSizes = {
	Very_Poor 		= {min=1,max=2,chance=100},
	Poor 			= {min=2,max=3,chance=98},
	Small 			= {min=3,max=4,chance=95},
	Modest 			= {min=4,max=6,chance=50},
	Average 		= {min=6,max=8,chance=20},
	Medium 			= {min=8,max=12,chance=5},
	Ample 			= {min=12,max=17,chance=2},
	Considerable 	= {min=17,max=24,chance=1.5},
	Sizable 		= {min=24,max=34,chance=1.25},
	Large 			= {min=34,max=49,chance=1},
	Abundant 		= {min=49,max=74,chance=0.5},
	Great 			= {min=74,max=125,chance=0.25},
	Substantial 	= {min=125,max=200,chance=0.1},
	Significant 	= {min=200,max=300,chance=0.05},
	Plentiful 		= {min=300,max=450,chance=0.025},
	Huge 			= {min=450,max=600,chance=0.01},
	Extremely_Large = {min=600,max=800,chance=0.005},
	Massive 		= {min=800,max=1200,chance=0.0025},
	Vast 			= {min=1200,max=2500,chance=0.001},
	Enormous 		= {min=2500,max=4900,chance=0.0005},
	Rich 			= {min=4900,max=20000,chance=0.00025},
	Gigantic 		= {min=20000,max=100000,chance=0.0001},
}

SM.rock_models = {}
SM.rock_models[1] = "models/props_foliage/rock_forest01.mdl"
SM.rock_models[2] = "models/props_foliage/rock_forest01a.mdl"
SM.rock_models[3] = "models/props_foliage/rock_forest01b.mdl"
SM.rock_models[4] = "models/props_foliage/rock_forest02.mdl"
SM.rock_models[5] = "models/props_mining/rock_caves01.mdl"
SM.rock_models[6] = "models/props_mining/rock_caves01a.mdl"
SM.rock_models[7] = "models/props_mining/rock_caves01b.mdl"
SM.rock_models[8] = "models/props_mining/rock_caves01c.mdl"

SM.language = {}
SM.language.refined = "Refined"
SM.language.ore = "Ore"

local LastSpawnTime = 0
SM.veinCount = 0

function SM.SpawnVeins()
	if (CurTime() < LastSpawnTime+server_settings.Int("SM_respawn_time")) then return end
	LastSpawnTime = CurTime()
	local SB = CAF.GetAddon("Spacebuild")
	if SM.enabled == true and SB then
		--how many asteroids can be spawned in this cycle
		local allowed = server_settings.Int("SM_veinlimit") - SM.veinCount
		local rCount = server_settings.Int("SM_respawn_count")
		if allowed >  rCount then allowed = rCount end
		--randomize random seeder (because we can :P)
		math.randomseed(os.time())
		
		--spawn asteroids
		if allowed > 0 then
			local spawned = 0
			
			for i=1,allowed do
				local model = SM.rock_models[math.random(table.Count(SM.rock_models))]
				local planet = SB.GetPlanets()[math.random(table.Count(SB.GetPlanets()))]
				--planet = SB.GetPlanets()[2]
				local pEnvo = planet.sbenvironment
				local pPos = planet:GetPos()
				local spawnAng = Angle(0,math.Rand(0,360),0)
				local spawnDepth = math.Rand(10,pEnvo.size-100)
				local spawnDist = math.sqrt(math.Rand(0,1)) * (pEnvo.size-100)
				local pos = (spawnAng:Forward() * spawnDist) + pPos
				
				local tracedata = {}
				local trace
				local spawnPosValid = false
				local spawnTerrainheight = 0
				for i=1,math.ceil(pEnvo.size / 10) do
					tracedata.start = pos + Vector(0,0,(i*10))
					tracedata.endpos = tracedata.start - Vector(0,0,pEnvo.size)
					tracedata.mask = MASK_PLAYERSOLID_BRUSHONLY
					trace = util.TraceLine(tracedata)
					if trace.HitWorld then
						spawnPosValid = (trace.HitTexture == "**displacement**")
						spawnTerrainheight = (trace.HitPos-pos).z
						break
					end
				end
				if (spawnPosValid) then
					--MsgN(spawnTerrainheight)
					pos = pos + Vector(0,0,spawnTerrainheight)
					--spawn asteroid entity
					local aent = ents.Create("vein")
					--aent:SetModel(model)
					aent:SetPos(pos)
					aent:Spawn()
					aent.vein = true
					aent.hitnormal = trace.HitNormal
					aent.lifetime = CurTime() + (server_settings.Int("SM_respawn_maxlife")*60)
					--setup resources for asteroid
					local nummin = math.random(1,4)
					
					--local maxcap = phys:GetVolume()/100 --max resources the asteroid can hold 
					--local curcap = maxcap
					for i=1,nummin do
						local pickedresource = nil
						local OnEarth = (planet.id == 1)
						local typepercent = math.random(1,100)
						if typepercent > 90 then rType = "gas" else rType = "ore" end
						while not pickedresource do
							local percent = math.random(1,SM.gResourcesTot)
							for k,v in pairs(SM.gResources) do
								if (percent >= v.raremin) and (percent <= v.raremax) then
									if (rType == v.group) then
										if OnEarth then
											if v.onearth then
												pickedresource = k
											end
										else
											pickedresource = k
										end
									end
								end
							end
						end
						--Got A resource.. now to add it
						--Starting the random veinsize
						local sizeindex = math.random(1,10000000) / 100000
						local veinsize
						local lowest = 101
						for k,v in pairs(SM.VeinSizes) do
							if (sizeindex <= v.chance) and (v.chance < lowest) then
								lowest = v.chance
								veinsize = k
							end
						end
						--Got the veinsize
						local maxcap = math.random(SM.VeinSizes[veinsize].min * 250,SM.VeinSizes[veinsize].max * 250)
						aent:AddResource({name=pickedresource,amount=maxcap,veinsize=veinsize})
						aent.totalResources = aent.totalResources + maxcap
					end
					aent.spawnpos = pos
					SM.veins[aent:EntIndex()] = aent
					spawned = spawned + 1
				end
			end
			
			--update asteroid count
			SM.veinCount = SM.veinCount + spawned
			Msg("GROUND MINING: "..tostring(spawned).." veins spawned. Total: "..tostring(SM.veinCount).."/"..tostring(server_settings.Int("SM_veinlimit")).."\n")
			--PrintTable(SM.veins)
		end
	end
end

function SM.RemoveVein(ent)
	if ent.vein then
		SM.veins[ent:EntIndex()] = nil
		--table.remove(SM.veins,ent:EntIndex())
		ent:Remove()
		
		SM.veinCount = SM.veinCount - 1
	end
end

function SM.RegisterResourceData(Valuepr1000,Valuepr1,Resourcename,Group,Type)
	--table.insert(SM.resources,{ })
	if (not Valuepr1000 && not Valuepr1) then return false, "No Values" end
	if (not Valuepr1) then Valuepr1 = Valuepr1000 / 1000 end
	if (Valuepr1 == 0) then Valuepr1 = Valuepr1000 / 1000 end
	if (Valuepr1000) then if (Valuepr1000 == 0 && Valuepr1 == 0) then return false, "No Values" end end
	if (not Type) then Type = "easy" end
	if (not Group) then Group = "natural" end
	if (not Resourcename) then return false, "No Resource name!" end
	if (SM.resources[Resourcename]) then return false, "Already registered "..Resourcename end
	SM.resources[Resourcename] = {type = tostring(Type),value = Valuepr1,res=Resourcename,group=Group,marked=math.random(90,110),trend="std"}
end
function SM.RegisterGroundMineralData(Resourcename,Group,Type,OnEarth,Rairity)
	--table.insert(SM.resources,{ })
	if (not Type) then Type = "easy" end
	if (not Group) then Group = "natural" end
	if (not Resourcename) then return false, "No Resource name!" end
	if (SM.gResources[Resourcename]) then return false, "Already registered "..Resourcename end
	
	SM.gResources[Resourcename] = {type = tostring(Type),onearth = OnEarth,raremin=SM.gResourcesTot+1,raremax=(SM.gResourcesTot+Rairity),group=Group}
	SM.gResourcesTot = SM.gResourcesTot + Rairity
end

function SM.FetchRandomTrend(nowtrend)
	if (nowtrend == "std") then
		local rnd = math.random(1,3)
		if (rnd == 1) then return "dwn" end
		if (rnd == 2) then return "std" end
		if (rnd == 3) then return "gup" end
	elseif (nowtrend == "dwn") then
		local rnd = math.random(1,2)
		if (rnd == 1) then return "dwn" end
		if (rnd == 2) then return "std" end
	elseif (nowtrend == "gup") then
		local rnd = math.random(1,2)
		if (rnd == 1) then return "std" end
		if (rnd == 2) then return "gup" end
	end
	return "std"
end

local function PhysgunPickup(ply , ent)
	local notallowed =  {"vein", "seller_machine"}
	if table.HasValue(notallowed, ent:GetClass()) then
		return false
	end
end
hook.Add("PhysgunPickup", "SM_Block_Physgun", PhysgunPickup) 


function SM.Think()
	SM.SpawnVeins()
	local dist = 0
	local plinger = false
	for k,v in pairs(player:GetAll()) do
		for k2,v2 in pairs(SM.veins) do
			dist = v2:GetPos():Distance(v:GetPos())
			--MsgN("Compared p"..k.." to "..k2.." dist: "..dist)
			if dist < 20 then plinger = true end
		end
		if plinger then
			--ErrorNoHalt("PLING!")
			if not v.ms_plinger then
				v:EmitSound("phx/hmetal2.wav")
			end
			v.ms_plinger = true
		else
			v.ms_plinger = false
		end
	end
end
hook.Add("Think", "Seller_ThinkyStuff", SM.Think)

function SM.__Construct()
	if status then return false, "Already Active!" end
	if not CAF.GetAddon("Resource Distribution") or not CAF.GetAddon("Resource Distribution").GetStatus() then return false, "Resource Distribution is required and needs to be Active!" end
	
	SM.enabled = true
	status = true
	return true
end

function SM.__Destruct()
	--TODO: remove asteroids on disable/destruct.
	SM.enabled = false
	status = false
	return false, "Disable not implemented"
end

function SM.GetRequiredAddons()
	return {"Resource Distribution"}
end

function SM.GetStatus()
	return status
end

function SM.GetVersion()
	return 0.10, "Alpha"
end

/**
	Get any custom options this Custom Addon Class might have
*/
function SM.GetExtraOptions()
	return {}
end

/**
	Get the Custom String Status from this Addon Class
*/
function SM.GetCustomStatus()
	return "Not Implemented Yet"
end

/**
	You can send all the files from here that you want to add to send to the client
*/
function SM.AddResourcesToSend()
	
end


CAF.RegisterAddon("Selling Machine", SM, "4") 

